package com.educate.book.rpc.provide.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Resource;

import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.educate.book.dao.ItemDao;
import com.educate.book.model.bo.ItemBO;
import com.educate.book.model.po.Item;
import com.educate.book.rpc.api.ItemService;
import com.educate.common.utils.converter.ListUtils;
import com.educate.common.utils.exception.AppException;
import com.educate.common.web.BeanUtils;
import com.educate.common.web.IdGen;

import lombok.extern.log4j.Log4j2;

@Log4j2
@Service(
        version = "${api.service.version}",
        application = "${dubbo.application.id}",
        protocol = "${dubbo.protocol.id}",
        registry = "${dubbo.registry.id}",
        timeout = 2000
)
public class ItemServiceImpl implements ItemService {

    @Resource ItemDao itemDao;

    @Override
    public String create(ItemBO bo) {
    	bo.setItemId(IdGen.uuid());
    	bo.setCrateTime(new Date());
    	if(StringUtils.isNotEmpty(bo.getParentId())) {
    		Item parentItem = itemDao.queryBYParentId(bo.getParentId());
        	bo.setLevel(parentItem.getLevel()+1);
        	//同一层是否有同名
    		Item sameNameItem = itemDao.queryByParentIdAndName(bo.getParentId(), bo.getName());
    		if(null!=sameNameItem)
    			return "-1";
    	}else{
    		bo.setLevel(1);
    	}
    	itemDao.insert(bo);
    	return bo.getItemId();
    }
    /**
     * 
     * @param parentId
     * @param child
     * @return
     */
    private Item findItemById(String parentId,List<Item> child) {
    	for (Item item : child) {
			if(parentId.equals(item.getParentId())) {
				
			}
		}
    	return null;
    }

    @Override
    public void delete(ItemBO bo) {
    	itemDao.delete(bo);
    }

    @Override
    public void delete(String itemId) {
    	itemDao.deleteById(itemId);
    }

    @Override
    public ItemBO detail(String itemId) {
        Optional<Item> optional = itemDao.findById(itemId);
        if (!optional.isPresent()) {
            throw new AppException("不存在的实例");
        }
        return new ItemBO(optional.get());
    }

    @Override
    public ItemBO detail(ItemBO bo) {
        return detail(bo.getItemId());
    }

    @Override
    public void update(ItemBO bo) {
        Optional<Item> optional = itemDao.findById(bo.getItemId());
        if (!optional.isPresent()) {
            throw new AppException("不存在的实例");
        }
        BeanUtils.copyPropertiesNonEmpty(bo, optional.get());
        itemDao.save(optional.get());
    }

    @Override
    public Page<ItemBO> query(ItemBO bo) {
        return itemDao.query(bo, bo.pageable()).map(ItemBO::new);
    }

    @Override
    public List<ItemBO> list(ItemBO bo) {
        List<Item> result = itemDao.findAll();
        return ListUtils.map(result, ItemBO::new);
    }

	@Override
	public List<Item> queryAll() {
		List<Item> result = itemDao.findAll();
		Item heightItem = itemDao.queryMaxLevelItem();
		List<Item> tempItemList = null;
		Map<String,List<Item>> map = new HashMap<String,List<Item>>();
		List<Item> tempList_1 = new ArrayList<Item>();
		for(int i=heightItem.getLevel();i>0;i--){
			tempItemList = itemDao.queryItemByLevel(i);
			Map<String,List<Item>> map2 = new HashMap<String,List<Item>>();
			map2.putAll(map);
			map = new HashMap<String,List<Item>>();
			for (Item item : tempItemList) {
				if(i==heightItem.getLevel()){// 最深层
					if(map.containsKey(item.getParentId())){
						List<Item> tempList = map.get(item.getParentId());
						tempList.add(item);
						map.put(item.getParentId(), tempList);
					}
					else{
						List<Item> tempList = new ArrayList<Item>();
						tempList.add(item)	;
						map.put(item.getParentId(), tempList);
					}
				}else{
					if(i>1){
						if (map2.containsKey(item.getItemId())) { //有子列表
							List<Item> temp1 = map2.get(item.getItemId());
							List<Item> temp2 = new ArrayList<Item>();
							item.setChildItem(temp1);
							temp2.add(item);
							if(map.containsKey(item.getParentId())) {
								// 如已有存在的key value 
								List<Item> temp3 = map.get(item.getParentId());
								temp3.add(item);
								map.put(item.getParentId(), temp3);
							}else
								map.put(item.getParentId(), temp2);
						}else{
							List<Item> temp2 = new ArrayList<Item>();
							temp2.add(item);
							map.put(item.getParentId(), temp2);
						}
					}
					if(i==1){ // 最上层
						if(map2.containsKey(item.getItemId())){
							List<Item> tempList = map2.get(item.getItemId());
							item.setChildItem(tempList);
							tempList_1.add(item);
//							map.put("childItem", item);
						}else{
							tempList_1.add(item);
						}
						map.put("childItem", tempList_1);
					}
				}
				System.out.println(JSONObject.toJSON(map));
			}
			//数据转回map1
			
		}
//		JSONObject itemJSON = new JSONObject();
//		itemJSON.put("itemList", map.get("childItem"));
//		String jsonResult = JSONObject.toJSONString(map);
		return map.get("childItem");
	}
	
	private List<Item> findItem(String parentId,List<Item> list){
		List<Item> returnList = new ArrayList<Item>();
		for (Item item : list) {
			JSONObject json = (JSONObject)JSONObject.toJSON(item);
			if (json.containsKey("parentId") && parentId.equals(json.getString("parentId"))) {
				returnList.add(item);
			}
		}
		return returnList;
	}
	@Override
	public Object getItemByParentId(String parentId) {
		Optional<Item> optional = itemDao.findById(parentId);
        if (!optional.isPresent()) {
            throw new AppException("不存在的实例 ,itemid="+parentId);
        }
        Item parentItem = optional.get();
        List<String> ids = new ArrayList<String>();
        ids.add(parentId);
        List<Item> allItemList = new ArrayList<Item>();
        allItemList.add(parentItem);
        int level = 1;
        do{
        	List<Item> list = itemDao.getItemByParentId(ids);
        	if(null!=list && list.size()>0){
        		level++;
        		allItemList.addAll(list);
        		ids = new ArrayList<String>();
        		for (Item item : list) {
					ids.add(item.getItemId());
				}
        	}else
        		break;
        	
        }
        while(true);
        
        Map<String,List<Item>> map = new HashMap<String,List<Item>>();
        Map<String,List<Item>> map2 = new HashMap<String,List<Item>>();
        int index = parentItem.getLevel()+level;
        for (int i = index; index >parentItem.getLevel(); index--) {
        	map2 = map;
			for (Item item : allItemList) {
				if(item.getLevel()==index) { //最深层
					if(index==parentItem.getLevel()+level) {
						if(map.containsKey(item.getParentId())) {
							List<Item> temp = map.get(item.getParentId());
							temp.add(item);
							map.put(item.getParentId(), temp);
						}
						else {
							List<Item> list = new ArrayList<Item>();
							list.add(item);
							map.put(item.getParentId(), list);
						}
					}else {
						if(index>parentItem.getLevel()){
							if (map2.containsKey(item.getItemId())) { //有子列表
								List<Item> temp1 = map2.get(item.getItemId());
								List<Item> temp2 = new ArrayList<Item>();
								item.setChildItem(temp1);
								temp2.add(item);
								if(map.containsKey(item.getParentId())) {
									// 如已有存在的key value 
									List<Item> temp3 = map.get(item.getParentId());
									temp3.add(item);
									map.put(item.getParentId(), temp3);
								}else
									map.put(item.getParentId(), temp2);
							}else{
								List<Item> temp2 = new ArrayList<Item>();
								temp2.add(item);
								map.put(item.getParentId(), temp2);
							}
						}
						if(index==parentItem.getLevel()){ // 最上层
							List<Item> list = map2.get(parentItem.getItemId());
							parentItem.setChildItem(list);
						}
					}
					
				}
			}
			
		}
        return parentItem;
	}
}
